gusucode.com > 现代通信系统——使用MATLAB(+全部程序) > 现代通信系统——使用MATLAB(+全部程序)/现代通信系统——使用MATLAB(+全部程序)/Matlab 程序/Chapter8/viterbi.m
function [decoder_output,survivor_state,cumulated_metric]=viterbi(G,k,channel_output) %VITERBI The Viterbi decoder for convolutional codes % [decoder_output,survivor_state,cumulated_metric]=viterbi(G,k,channel_output) % G is a n x Lk matrix each row of which % determines the connections from the shift register to the % n-th output of the code, k/n is the rate of the code. % survivor_state is a matrix showing the optimal path through % the trellis. The metric is given in a separate function metric(x,y) % and can be specified to accommodate hard and soft decision. % This algorithm minimizes the metric rather than maximizing % the likelihood. n=size(G,1); % check the sizes if rem(size(G,2),k) ~=0 error('Size of G and k do not agree') end if rem(size(channel_output,2),n) ~=0 error('channel output not of the right size') end L=size(G,2)/k; number_of_states=2^((L-1)*k); % Generate state transition matrix, output matrix, and input matrix. for j=0:number_of_states-1 for l=0:2^k-1 [next_state,memory_contents]=nxt_stat(j,l,L,k); input(j+1,next_state+1)=l; branch_output=rem(memory_contents*G',2); nextstate(j+1,l+1)=next_state; output(j+1,l+1)=bin2deci(branch_output); end end state_metric=zeros(number_of_states,2); depth_of_trellis=length(channel_output)/n; channel_output_matrix=reshape(channel_output,n,depth_of_trellis); survivor_state=zeros(number_of_states,depth_of_trellis+1); % Start decoding of non-tail channel outputs. for i=1:depth_of_trellis-L+1 flag=zeros(1,number_of_states); if i <= L step=2^((L-i)*k); else step=1; end for j=0:step:number_of_states-1 for l=0:2^k-1 branch_metric=0; binary_output=deci2bin(output(j+1,l+1),n); for ll=1:n branch_metric=branch_metric+metric(channel_output_matrix(ll,i),binary_output(ll)); end if((state_metric(nextstate(j+1,l+1)+1,2) > state_metric(j+1,1)... +branch_metric) | flag(nextstate(j+1,l+1)+1)==0) state_metric(nextstate(j+1,l+1)+1,2) = state_metric(j+1,1)+branch_metric; survivor_state(nextstate(j+1,l+1)+1,i+1)=j; flag(nextstate(j+1,l+1)+1)=1; end end end state_metric=state_metric(:,2:-1:1); end % Start decoding of the tail channel-outputs. for i=depth_of_trellis-L+2:depth_of_trellis flag=zeros(1,number_of_states); last_stop=number_of_states/(2^((i-depth_of_trellis+L-2)*k)); for j=0:last_stop-1 branch_metric=0; binary_output=deci2bin(output(j+1,1),n); for ll=1:n branch_metric=branch_metric+metric(channel_output_matrix(ll,i),binary_output(ll)); end if((state_metric(nextstate(j+1,1)+1,2) > state_metric(j+1,1)... +branch_metric) | flag(nextstate(j+1,1)+1)==0) state_metric(nextstate(j+1,1)+1,2) = state_metric(j+1,1)+branch_metric; survivor_state(nextstate(j+1,1)+1,i+1)=j; flag(nextstate(j+1,1)+1)=1; end end state_metric=state_metric(:,2:-1:1); end % Generate the decoder output from the optimal path. state_sequence=zeros(1,depth_of_trellis+1); state_sequence(1,depth_of_trellis)=survivor_state(1,depth_of_trellis+1); for i=1:depth_of_trellis state_sequence(1,depth_of_trellis-i+1)=survivor_state((state_sequence(1,depth_of_trellis+2-i)... +1),depth_of_trellis-i+2); end decodeder_output_matrix=zeros(k,depth_of_trellis-L+1); for i=1:depth_of_trellis-L+1 dec_output_deci=input(state_sequence(1,i)+1,state_sequence(1,i+1)+1); dec_output_bin=deci2bin(dec_output_deci,k); decoder_output_matrix(:,i)=dec_output_bin(k:-1:1)'; end decoder_output=reshape(decoder_output_matrix,1,k*(depth_of_trellis-L+1)); cumulated_metric=state_metric(1,1);